using CfgTable;
using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using System;
using System.Collections.Generic;
using System.Linq;

namespace IQIGame.Onigao.GamePlay
{
    public class UIGMList : UIBaseWindow
    {
        /// <summary>
        /// 静态配置
        /// </summary>
        private static UICreateConfig _createConfig = new()
        {
            prefabName = nameof(UIGMList),
            layer = EUILayer.Notify,
        };

        /// <summary>
        /// 创建UI的配置
        /// </summary>
        public override IUICreateConfig createConfig => _createConfig;

        #region Template Generate,don't modify
        protected partial class UIB_UIGMList
        {
            #region ObjectBinding Generate 
            public IQIGame.Onigao.Framework.ExButton btnClose { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btnExcuteAll { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btnSearch { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btnRest { protected set; get; }
            public IQIGame.Onigao.Framework.ExInputField inputCmd { protected set; get; }
            public IQIGame.Onigao.Framework.ExInputField inputCmdArgs { protected set; get; }
            public IQIGame.Onigao.Framework.ExInputField inputSearch { protected set; get; }
            public UnityEngine.UI.ExLoopVerticalScrollRect loopVerticalScrollSubType { protected set; get; }
            public UnityEngine.UI.ExLoopVerticalScrollRect loopVerticalScrollCmdCells { protected set; get; }
            public UnityEngine.GameObject toggleType { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btnExcuteCmd { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btnHitory { protected set; get; }
            public UnityEngine.GameObject uIGmHistory { protected set; get; }
            public virtual void InitBinding(ObjectBinding __binding)
            {
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("btnClose", out var __tbv0);
                this.btnClose = __tbv0;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("btnExcuteAll", out var __tbv1);
                this.btnExcuteAll = __tbv1;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("btnSearch", out var __tbv2);
                this.btnSearch = __tbv2;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("btnRest", out var __tbv3);
                this.btnRest = __tbv3;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExInputField>("inputCmd", out var __tbv4);
                this.inputCmd = __tbv4;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExInputField>("inputCmdArgs", out var __tbv5);
                this.inputCmdArgs = __tbv5;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExInputField>("inputSearch", out var __tbv6);
                this.inputSearch = __tbv6;
                __binding.TryGetVariableValue<UnityEngine.UI.ExLoopVerticalScrollRect>("loopVerticalScrollSubType", out var __tbv7);
                this.loopVerticalScrollSubType = __tbv7;
                __binding.TryGetVariableValue<UnityEngine.UI.ExLoopVerticalScrollRect>("loopVerticalScrollCmdCells", out var __tbv8);
                this.loopVerticalScrollCmdCells = __tbv8;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("toggleType", out var __tbv9);
                this.toggleType = __tbv9;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("btnExcuteCmd", out var __tbv10);
                this.btnExcuteCmd = __tbv10;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("btnHitory", out var __tbv11);
                this.btnHitory = __tbv11;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("uIGmHistory", out var __tbv12);
                this.uIGmHistory = __tbv12;
            }
            #endregion ObjectBinding Generate 
        }
        #endregion Template Generate,don't modify


        protected UIB_UIGMList ui { get; set; }

        protected override void BeforeInit()
        {
            ui = new UIB_UIGMList();
            ui.InitBinding(this.csObjBind);
        }
        private UIGmHistory uIGmHistory = null;
        LoopScrollAdapter<UIN_GMMould> cmdCells = null;
        ListScrollAdapter<UIN_GMType> gmTypes = null;
        LoopScrollAdapter<UIN_GMSubType> gmSubTypes = null;
        private const int MaxHistoryEntries = 30; //最多保存30条历史记录
        int selectedIndexMainType = -1;
        GmType gmTypeMain = null;
        UIN_GMSubType gmSubTypeCell = null;
        List<UD_GMCmd> dataList = new(8);
        List<UD_GMCmd> dataCurrList = new(8);

        PlayerPreferenceString cacheGMCmd = new PlayerPreferenceString(PlayerPrefsConst.CacheGMCmd, string.Empty);
        PlayerPreferenceString cacheGMCmdArgs = new PlayerPreferenceString(PlayerPrefsConst.CacheGMCmdArgs, string.Empty);
        PlayerPreferenceString historyLog = null;
        protected override void OnInit()
        {
            this.cmdCells = this.InitLoopScroll<UIN_GMMould>(this.ui.loopVerticalScrollCmdCells, this.OnLoopNodeChanged);
            this.gmTypes = this.InitListScroll<UIN_GMType>(this.ui.toggleType, this.OnTypeChanged);
            this.gmTypes.InitUnitSelected(UnitSelectType.ByExToggle, this.OnTypeSelected);
            this.gmSubTypes = this.InitLoopScroll<UIN_GMSubType>(this.ui.loopVerticalScrollSubType, this.OnSubTypeChanged);
            this.gmSubTypes.InitUnitSelected(UnitSelectType.ByExToggle, this.OnSubTypeSelected);
            this.uIGmHistory = this.InitChildNode<UIGmHistory>(this.ui.uIGmHistory);
            this.ui.btnClose.onClick.AddListener(this.Close);

            this.ui.btnRest.onClick.AddListener(this.OnClickReset);
            this.ui.btnSearch.onClick.AddListener(this.OnClickSearch);
            this.ui.btnExcuteCmd.onClick.AddListener(this.OnClickExcCmd);
            this.ui.btnExcuteAll.onClick.AddListener(this.OnClickExcAll);
            this.ui.btnHitory.onClick.AddListener(this.OnClickHistory);
            this.ui.btnExcuteAll.SetActive(false); // 没批处理执行命令

            this.ui.inputCmd.text = cacheGMCmd;
            this.ui.inputCmdArgs.text = cacheGMCmdArgs;
        }

        protected override void OnShow(UIBaseData data)
        {
            var types = GameCmdModule.Instance.MainTypes;
            this.gmTypes.RefillCells(types.Count, 0);
            GM.CloseGM();
        }

        protected override void OnHide()
        {

        }

        protected override void OnDispose()
        {
            this.ClearDataList();
            GM.ShowGm();
        }

        #region 单击
        void OnClickReset()
        {
            this.ViewSubType(this.gmSubTypeCell);
        }

        void OnClickSearch()
        {
            string strSearch = this.ui.inputSearch.text.Trim();
            if (string.IsNullOrEmpty(strSearch))
            {
                this.ViewSubType(this.gmSubTypeCell);
                return;
            }
            if (this.dataList.Count == 0)
            {
                return;
            }

            this.dataCurrList.Clear();
            foreach (var data in this.dataList)
            {
                if (data.IsContains(strSearch))
                {
                    this.dataCurrList.Add(data);
                }
            }

            this.cmdCells.RefillCells(this.dataCurrList.Count);
        }

        void OnClickExcCmd()
        {
            string cmd = this.ui.inputCmd.text.Trim();
            string cmdArgs = this.ui.inputCmdArgs.text.Trim();
            cacheGMCmd.Value = cmd;
            cacheGMCmdArgs.Value = cmdArgs;
            this.SendCmd(cmd, cmdArgs);
            AddHistory(cmd, cmdArgs);
        }
        private void AddHistory(string cmd, string cmdArgs)
        {
            var historyLog = new PlayerPreferenceString(PlayerPrefsConst.GMHistory, string.Empty);
            string currentLog = historyLog.Value;
            string[] logEntries = currentLog.Split('\n').Where(s => !string.IsNullOrEmpty(s)).ToArray();
            if (logEntries.Length == MaxHistoryEntries)
            {
                logEntries[logEntries.Length - 1] = "";
                currentLog = string.Join("\n", logEntries);
            }
            currentLog = cmd + "|" + DateTime.Now.ToString() + "|" + "指令输入" + "|" + cmdArgs + "\n" + currentLog;
            historyLog.Value = currentLog;
        }
        void OnClickExcAll()
        {
            // 执行当前页的所有命令
        }
        private void OnClickHistory()
        {
            this.uIGmHistory.Show();
        }
        #endregion


        async UniTask SendGMCmd(string cmd, string cmdArgs)
        {
            // 处理客户端命令
            switch (cmd)
            {
                case "exec":
                    {
                        //读表

                        TableCenter.gmBatchCmd.DataMap.TryGetValue(int.Parse(cmdArgs), out var obj);
                        string cmds = obj.Cmds;
                        //裁剪
                        List<string> operations = cmds.Split("|").ToList();
                        foreach (string op in operations)
                        {
                            //string output = op.Replace("/cmd ", "");//去掉“/cmd ”
                            int firstSpaceIndex = op.IndexOf(' '); // 找到第一个空格的索引
                            string command = op.Substring(0, firstSpaceIndex); // 从开始到第一个空格的字符串
                            string commandArgs = op.Substring(firstSpaceIndex + 1); // 从第一个空格后的字符到字符串末尾
                            // 服务器命令
                            var res = await GameCmdModule.NetCore.CS_exec(command, commandArgs);
                            if (res.IsFail)
                            {
                                FloatNotice.Instance.Show($"执行失败：GM命令执行命令：[${cmd} {cmdArgs}]");
                                break;
                            }
                        }
                        FloatNotice.Instance.Show($"成功执行：GM命令执行命令：[${cmd} {cmdArgs}]");

                    }
                    break;
                case "exit_level":
                    {
                        GameScenePlayUtil.LeaveLevel(0, 0, 0).Forget();
                        Close();
                    }
                    break;
                case "exit_battle":
                    {
                        CBattleLogicModule.NetCore.CS_RequestLeave();
                        Close();
                    }
                    break;
                case "reset_msg_awaiter":
                    if (string.IsNullOrWhiteSpace(cmdArgs))
                    {
                        MsgAsyncAwaiterAll.ClearAllMsgAwait();
                    }
                    else
                    {
                        MsgAsyncAwaiterAll.ClearMsgAwait(int.Parse(cmdArgs), int.Parse(cmdArgs));
                    }
                    break;
                case "set_fog":
                    var mapRoot = UIMapManager.Instance.GetMap(LevelPlayModule.Instance.levelPlay.regionCtrl.cfgRegionPack
                        .cfgRegionInstance.Id);
                    bool.TryParse(cmdArgs, out var fogSwitch);
                    mapRoot.GetLayer((int)StaticLayerType.FogLayer).root.SetActive(fogSwitch);
                    break;
                default:
                    // 服务器命令
                    var result = await GameCmdModule.NetCore.CS_exec(cmd, cmdArgs);
                    if (result.IsSuccess)
                    {
                        FloatNotice.Instance.Show($"成功执行：GM命令执行命令：[${cmd} {cmdArgs}]");
                    }
                    break;
            }
        }

        void OnTypeChanged(UIN_GMType item, int index)
        {
            var types = GameCmdModule.Instance.MainTypes;
            var objGmType = GameCmdModule.Instance.GetMainGmType(types[index]);
            item.Show(objGmType);
        }

        void OnTypeSelected(int index, UIN_GMType item)
        {
            this.selectedIndexMainType = index;
            this.ViewMainType(item);
        }

        void ViewMainType(UIN_GMType item)
        {
            gmTypeMain = item.gmType;
            int cnt = gmTypeMain.subTypes?.Count ?? 0;
            this.gmSubTypes.RefillCellsAndSelected(cnt, 0);
        }

        void OnSubTypeChanged(UIN_GMSubType item, int index)
        {
            GmType subType = gmTypeMain.subTypes[index];
            item.Show(subType);
        }

        void OnSubTypeSelected(int index, UIN_GMSubType item)
        {
            this.gmSubTypeCell = item;
            this.ViewSubType(item);
        }

        void ClearDataList()
        {
            foreach (var item in this.dataList)
            {
                item.Put2Pool();
            }
            this.dataList.Clear();
            this.dataCurrList.Clear();
        }

        void InitDataList(GmType subType)
        {
            var list = TableCenter.gmCmd.DataList;
            foreach (var cfg in list)
            {
                if (cfg.Type == subType.parentType && cfg.SubType == subType.type)
                {
                    switch (cfg.Type)
                    {
                        case 1:// 道具
                            InitItemInDataList(subType, cfg);
                            break;
                        case 2:
                            // 常用
                            InitType2InDataList(subType, cfg);
                            break;
                        default:
                            AddDataInDataList(cfg);
                            break;
                    }
                }
            }
            this.dataCurrList.AddRange(this.dataList);
        }

        void AddDataInDataList(CfgGmCmd cfg, string cmdValue = null, string name = null, int cid = 0)
        {
            var ud = UD_GMCmd.NewFromPool().Sync(cfg, cmdValue, name, cid);
            this.dataList.Add(ud);
        }

        void InitItemInDataList(GmType subType, CfgGmCmd cfg)
        {
            var listItems = TableCenter.item.DataList;
            foreach (var cfgData in listItems)
            {
                if (((int)cfgData.Type) == subType.type)
                {
                    AddDataInDataList(cfg, $"{cfgData.Id} {cfg.DefaultParam}", cfgData.Name, cfgData.Id);
                }
            }
        }

        void InitType2InDataList(GmType subType, CfgGmCmd cfg)
        {
            switch (subType.type)
            {
                case 0:
                    InitHeroInDataList(subType, cfg);
                    break;
                case 1:
                    InitPetInDataList(subType, cfg);
                    break;
                default:
                    AddDataInDataList(cfg);
                    break;
            }
        }

        void InitHeroInDataList(GmType subType, CfgGmCmd cfg)
        {
            var listHeros = TableCenter.hero.DataList;
            foreach (var cfgData in listHeros)
            {
                AddDataInDataList(cfg, $"{cfgData.Id}", cfgData.Name, cfgData.Id);
            }
        }

        void InitPetInDataList(GmType subType, CfgGmCmd cfg)
        {
            var listHeros = TableCenter.pet.DataList;
            foreach (var cfgData in listHeros)
            {
                AddDataInDataList(cfg, $"{cfgData.Id}", cfgData.Name, cfgData.Id);
            }
        }

        void ViewSubType(UIN_GMSubType item)
        {
            this.ClearDataList();
            if (item == null)
            {
                return;
            }
            GmType subType = item.gmType;
            this.InitDataList(subType);
            this.cmdCells.RefillCells(this.dataCurrList.Count);
        }

        void OnLoopNodeChanged(UIN_GMMould item, int index)
        {
            var data = this.dataCurrList[index];
            item.Show(data);
        }

        public void SendCmd(string cmd, string cmdArgs)
        {
            if (string.IsNullOrEmpty(cmd))
            {
                FloatNotice.Instance.Show("GM命令的CMD不能为空");
                return;
            }
            this.SendGMCmd(cmd, cmdArgs).Forget();
        }
    }
}
